﻿#ifndef __SS_ASIO_SESSION_H__
#define __SS_ASIO_SESSION_H__
#include <asio.hpp>
#include "memory/uniPointer.h"
//#include "../../StarSeekerBaseLib/ssBaseDefine.h"
#include "time/ssTime.h"
#include "container/ssBuffer.h"
#include "message/ssNetMsgHead.h"
#include "container/ssBytesQue.h"


#ifndef SS_ASIO_PACK_SIZE
#define SS_ASIO_PACK_SIZE		10240
#endif

namespace StarSeeker
{

enum eAsioClose:int
{
	CLOSE_NORMAL=0,
	CLOSE_BY_READ,
	CLOSE_BY_WRITE,
	CLOSE_BY_ACCEPT,
	CLOSE_BY_READBUF,
	CLOSE_BY_ACCEPT_FULL,
	CLOSE_BY_READ_FAST,
};

enum eParseState:int
{
	PARSE_NOTHING = 0,
	PARSE_DISCARD,
	PARSE_WAIT,
	PARSE_TOO_MANY
};

class ssAsioNetWork;

class ssAsioSession
{
	friend class ssAsioNetWork;
public:
	ssAsioSession(void);
	virtual ~ssAsioSession(void);
	//获取ID
	u32 GetID() { return m_sessionID; }
	//获取Socket对象
	SS_SHARED_PTR<asio::ip::tcp::socket>& GetSocket();
	//获取IP
	const std::string& GetIP() { return m_ip; }
private:
	//初始化
	bool Init(u32 id, SS_SHARED_PTR<asio::ip::tcp::socket>& socket, u32 recvBuffSize, u32 sendBuffSize, ssAsioNetWork* pNetMgr);
	//收包间隔检测 @启用功能 @间隔时间（毫秒）@临界次数
	void SetTimeCheck(bool timeCheck, i64 intervalTime = 100, u16 checkCount = 20);
	//关闭socket
	void Close(eAsioClose errType, i32 err);
protected:
	//收到后的处理
	bool OnReceive();
	//分析数据包
	eParseState ParseData();
	//从接收缓冲区中复制一个包
	virtual char* CopyMsgFromRecvBuffer(ssNetMsgBasicHead* msg);


	bool					m_timeCheck;	//是否检测收包间隔
	i64						m_intervalTime;	//收包间隔,毫秒
	i64						m_lastTime;		//上次收包时间,毫秒
	u16						m_fastCount;	//频繁次数,超过20次断线
	u16						m_checkCount;	//超过这个次数就触发事件
	SS_SHARED_PTR<asio::ip::tcp::socket>	m_socket;
	ssBuffer				m_recvBuf;		//接收缓存
	u32						m_sessionID;	//连接编号,0表示无效的
	std::string				m_ip;
	ssAsioNetWork*			m_pNetMgr;
	ssBytesQue				m_sendQue;		//发送队列
	bool					m_sending;		//发送中
	u32						m_fullCount;	//接受缓冲区满提示次数，超过50次则断开连接
};

typedef SS_SHARED_PTR<ssAsioSession> ssAsioSessionPtr;

}
#endif
